package com.zyr.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zyr.model.SecurityUser;
import com.zyr.domain.vo.LoginVo;
import com.zyr.constraint.AuthConstants;
import com.zyr.constraint.BusinessEnum;
import com.zyr.constraint.JwtConstants;
import com.zyr.model.Result;
import com.zyr.model.User;
import com.zyr.mapper.UserMapper;
import com.zyr.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import com.zyr.utils.JwtUtils;

import java.time.Duration;
import java.util.HashMap;

/**
 * @author 张雨润
 * @date 2024/7/25 下午8:23
 * @Description
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Result<T> login(LoginVo loginVo) {
        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(loginVo.getUsername(), loginVo.getPassword());
        Authentication authentication = authenticationManager.authenticate(authToken);
        // 设置认证过后的authentication到securityContextHolder上下文
        SecurityContextHolder.getContext().setAuthentication(authentication);
        if (authentication.isAuthenticated()) {
            Object principal = authentication.getPrincipal();
            SecurityUser securityUser = (SecurityUser) principal;
            HashMap<String, String> map = new HashMap<>();
            map.put("id", securityUser.getUser().getId().toString());
            map.put("username", securityUser.getUser().getUsername());
            String token = JwtUtils.generateToken(map);
            String jsonPrincipal = JSONObject.toJSONString(principal);
            // 前缀+token 作为 key , principle作为value，过期时间30min
            stringRedisTemplate.opsForValue().set(AuthConstants.LOGIN_TOKEN_PREFIX + token, jsonPrincipal, Duration.ofSeconds(JwtConstants.JWT_EXPIRATION));
            return Result.success(token);
        } else {
            return Result.error(BusinessEnum.OPERATION_FAIL);
        }

    }

    @Override
    public Result<T> logout(HttpServletRequest request) {
        String header = request.getHeader(AuthConstants.AUTHORIZATION);
        if (header != null && header.startsWith(AuthConstants.BEARER)) {
            // 删除redis中的token
            Boolean delete = stringRedisTemplate.delete(AuthConstants.LOGIN_TOKEN_PREFIX + header.replace(AuthConstants.BEARER, ""));
            if (Boolean.TRUE.equals(delete)){
                return Result.success();
            }
        }
        return Result.error(500,"登出失败");
    }
}
